home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-12 | 11.5 KB | 465 lines | [TEXT/CWIE] |
- /*******************************************************************************\
- | |
- | CVersCaption.cp ©1997 John C. Daub. All rights reserved |
- | |
- | See the file "CVersCaption README" for full details, instructions, changes, |
- | licensing agreement, etc. Due to the important information included in that |
- | file, if you did not receive a copy of it, please contact the author for |
- | a copy. |
- | |
- | John C. Daub <mailto:hsoi@eden.com> |
- | <http://www.eden.com/~hsoi/> <http://www.eden.com/~hsoi/prog.html> |
- | |
- \*******************************************************************************/
-
-
- #ifdef PowerPlant_PCH
- #include PowerPlant_PCH
- #endif
-
- #include "CVersCaption.h"
-
- #include <LString.h>
- #include <UException.h>
- #include <LStream.h>
- #include <UDrawingUtils.h>
- #include <UTextTraits.h>
- #include <UMemoryMgr.h>
-
-
- #if ( __PowerPlant__ < 0x01608000 ) // version 1.6/CW11
-
- //========================================================================
- // • CreateFromStream [public, static]
- //========================================================================
- // Only compiled if the RegisterClass_() macro doesn't exist. Saves a bit
- // of space in and of itself, plus keeps down redundancy.
-
- CVersCaption*
- CVersCaption::CreateFromStream(
- LStream *inStream )
- {
- #ifdef DEBUG_NEW
- return ( NEW CVersCaption( inStream ) );
- #else
- return ( new CVersCaption( inStream ) );
- #endif
-
- }
-
- #endif
-
-
- //========================================================================
- // • CVersCaption [public]
- //========================================================================
- // Default constructor
-
- CVersCaption::CVersCaption()
- : mVersion( 0x0000 ),
- mUseShortString( false ),
- mUseCountryCode( false )
- {
- mText = "\p";
-
- InitVersCaption();
- }
-
-
- //========================================================================
- // • CVersCaption [public]
- //========================================================================
- // Copy constructor
-
- CVersCaption::CVersCaption(
- const CVersCaption &inOriginal )
- : LCaption( inOriginal ),
- mVersion( inOriginal.mVersion ),
- mUseShortString( inOriginal.mVersion ),
- mUseCountryCode( inOriginal.mUseCountryCode )
- {
- // there's no need to call InitVersCaption() here since we
- // should already have this information
- }
-
-
- //========================================================================
- // • operator= [public]
- //========================================================================
- // Assignment operator
-
- CVersCaption&
- CVersCaption::operator=(
- const CVersCaption &inOriginal )
- {
- // check for self-assignment
- if ( this == &inOriginal ) {
- return *this;
- }
-
- LCaption::operator=(inOriginal);
- mVersion = inOriginal.mVersion;
- mUseShortString = inOriginal.mUseShortString;
- mUseCountryCode = inOriginal.mUseCountryCode;
-
- // LCaption doesn't explictly provide its own assignment operator,
- // so to not risk losing vital data, we'll (re)assign here.
-
- //mText = inOriginal.mText;
- SetDescriptor( mText );
- SetTextTraitsID( inOriginal.mTxtrID );
-
- return *this;
- }
-
-
- //========================================================================
- // • CVersCaption [public]
- //========================================================================
- // Parameterized constructor
-
- CVersCaption::CVersCaption(
- const SPaneInfo &inPaneInfo,
- ConstStringPtr inString,
- ResIDT inTextTraitsID,
- Boolean inUseShortString,
- Boolean inUseCountryCode )
- : LCaption( inPaneInfo, inString, inTextTraitsID ),
- mVersion( 0x0000 ),
- mUseShortString( inUseShortString ),
- mUseCountryCode( inUseCountryCode )
- {
- mText = "\p";
-
- InitVersCaption();
- }
-
-
- //========================================================================
- // • CVersCaption [public]
- //========================================================================
- // LStream constructor
-
- CVersCaption::CVersCaption(
- LStream *inStream )
- : LCaption( inStream ),
- mVersion( 0x0000 )
- {
- mText = "\p";
-
- inStream->ReadData( &mUseShortString, sizeof(Boolean) );
- inStream->ReadData( &mUseCountryCode, sizeof(Boolean) );
-
- InitVersCaption();
- }
-
-
- //========================================================================
- // • ~CVersCaption [public, virtual]
- //========================================================================
- // Destructor
-
- CVersCaption::~CVersCaption()
- {
- // nothing
- }
-
-
- //========================================================================
- // • InitVersCaption [private]
- //========================================================================
- //
- // Private initializer of the object
- //
- // Gets the 'vers' #1 resource resource. Return 0 if resource missing.
- // Convert resource's NumVersion (see Types.h) to the version "string"
- //
- // This does assume that the application's resource fork is the current
- // resource file. If it is not and/or a 'vers' #1 resource doesn't
- // exist, unpredictable results can occur.
-
- void
- CVersCaption::InitVersCaption()
- {
- // Get the 'vers' 1 resource
-
- Handle versH = ::GetResource( 'vers', 1 );
-
- if ( versH == nil ) {
-
- OSErr err = ::ResError();
-
- // shouldn't need more than a signal...this is such a
- // vital part of a complete application and something that
- // you're bound to forget...so I doubt it will fail in the
- // real world cause you SHOULD catch this before you ship.
-
- // actually, I've heard that GetResource() will never produce
- // resNotFound (so of course, check for the nil handle).
- // this error handler might want to be revamped for later
- // (but really, you should have a 'vers' 1 resource in your app
- // anyways...the only reason I could then see it failing would
- // be from a memFullErr or something)
-
- if ( err == resNotFound ) {
- SignalPStr_( "\p'vers' #1 resource not found" );
- return; // so we don't crash
- }
-
- // but just in case (e.g. memFullErr or something), we'll
- // prepare
-
- ThrowIfOSErr_(err);
- }
-
- // if they wish to use the short string (VersRec.shortVersion), we'll just
- // extract that and return (1.2 addition)
-
- if ( GetUseShortString() ) {
-
- // (just for sanity, if mUseShortString == true, mUseCountryCode
- // doesn't really matter)
-
- mText += (*(VersRecHndl)versH)->shortVersion;
- ::ReleaseResource(versH);
-
- return;
- }
-
- // if they wish to print the coutry code, let's extract out the code
- // right now. we'll get the string in a bit. (1.2 addition)
-
- Int16 theCountryCode;
-
- if ( GetUseCountryCode() ) {
- theCountryCode = (*(VersRecHndl)versH)->countryCode;
- }
-
- // if not, we'll continue....
-
- // copy out the version information
-
- SetVersion( *((Uint32 *)(*versH)) );
-
- // we can dump the 'vers' resource
-
- if ( versH ) {
- ::ReleaseResource( versH );
- versH = nil;
- }
-
-
- // set ver1-3, relStatus, prerelNum from the version info.
- // Note that the first two bytes are in an unusual format.
-
- Uchar ver1,
- ver2,
- ver3,
- relStatus,
- prerelNum;
-
- ver1 = ((Uchar *)&mVersion)[0];
- ver1 = (((ver1 & 0xF0 ) >> 4) * 10) + (ver1 & 0x0F);
- ver2 = (((Uchar *)&mVersion)[1] & 0xF0) >> 4;
- ver3 = (((Uchar *)&mVersion)[1] & 0x0F);
- relStatus = ((Uchar *)&mVersion)[2];
- prerelNum = ((Uchar *)&mVersion)[3];
- prerelNum = (((prerelNum & 0xF0 ) >> 4) * 10) + (prerelNum & 0x0F); // 1.1 fix
-
- // Insert v1 and v2 into our version string
-
- Str255 tmpStr;
- StringHandle dotH;
-
- ::NumToString((Int32)ver1, tmpStr );
- LString::AppendPStr( mText, tmpStr );
-
- dotH = ::GetString( STR_dot );
- ThrowIfResFail_(dotH);
-
- {
- // not really needed, but can't hurt to be safe
- StHandleLocker lock((Handle)dotH);
-
- LString::AppendPStr( mText, *dotH );
-
- ::NumToString( (Int32)ver2, tmpStr );
- LString::AppendPStr( mText, tmpStr );
-
- // to make it nicer, we only print the third number if it's non-zero.
-
- // if you always want all three matches, remove the if statement
-
- if ( ver3 ) {
- LString::AppendPStr( mText, *dotH );
-
- ::NumToString( (Int32)ver3, tmpStr );
- LString::AppendPStr( mText, tmpStr );
- }
- }
-
- ::ReleaseResource((Handle)dotH);
- dotH = nil;
-
-
- // if the release status is development, alpha or beta, add
- // a 'd', 'a', or 'b' to our version string.
- // if you do something like "GM" or "FC1/FC2/etc" before you
- // ship a product, you could add in another case here for that
- // and then just conditionally wrap it with preprocessor macros
- // to be compiled out when you #define __DEBUG__ to false (or
- // whatever debugger macros are turned off).
-
- StringHandle relH;
-
- switch( relStatus ) {
-
- case 0x20: {
-
- // development
- relH = ::GetString(STR_devel);
- ThrowIfResFail_(relH);
- break;
- }
-
- case 0x40: {
-
- // alpha
- relH = ::GetString(STR_alpha);
- ThrowIfResFail_(relH);
- break;
- }
-
- case 0x60: {
-
- // beta
- relH = ::GetString(STR_beta);
- ThrowIfResFail_(relH);
- break;
- }
-
- case 0x80: {
-
- // nothing
-
- break;
- }
-
- default: {
-
- // it'd be odd if we hit the default, so we'll signal
- // for possible error
-
- SignalPStr_("\pUnknown relStatus" );
- break;
- }
- }
-
- // if we've added a 'd', 'a', or 'b', print the
- // pre-release number at the end.
-
- if ( relStatus != 0x80 ) {
-
- {
- StHandleLocker lock((Handle)relH);
- LString::AppendPStr(mText,*relH);
- }
-
- if (relH) {
- ::ReleaseResource((Handle)relH);
- relH = nil;
- }
-
- ::NumToString( (Int32)prerelNum, tmpStr );
- LString::AppendPStr( mText, tmpStr );
- }
-
- // lastly, if we want to use the country code, let's stick that
- // on.
-
- if ( GetUseCountryCode() ) {
-
- Str255 countryStr;
- ::GetIndString( countryStr, STRx_countries, theCountryCode + 1 );
- LString::AppendPStr( mText, countryStr );
- }
-
- }
-
-
- //========================================================================
- // • ActivateSelf [protected, virtual]
- //========================================================================
- //
- // We need to force a redraw when the pane becomes active so that it
- // will draw properly.
-
- void
- CVersCaption::ActivateSelf()
- {
- if ( mActive == triState_On ) {
- Refresh();
- }
- }
-
-
- //========================================================================
- // • DeactivateSelf [protected, virtual]
- //========================================================================
- //
- // We need to force a redraw when the pane becomes deactivated
-
- void
- CVersCaption::DeactivateSelf()
- {
- if ( mActive == triState_Off || mActive == triState_Latent ) {
- Refresh();
- }
- }
-
-
- //========================================================================
- // • DrawSelf [protected, virtual]
- //========================================================================
- //
- // Similar to LCaption::DrawSelf, but if the pane isn't active, the
- // text is drawn in a "dimmed" state.
-
- void
- CVersCaption::DrawSelf()
- {
- Rect frame;
- CalcLocalFrameRect(frame);
-
- Int16 just = UTextTraits::SetPortTextTraits(mTxtrID);
-
- RGBColor textColor;
- ::GetForeColor(&textColor);
-
- ApplyForeAndBackColors();
-
- if ( !IsActive() ) {
-
- // lighten the text color a bit
-
- textColor.red = textColor.red + 65535 >> 1;
- textColor.green = textColor.green + 65535 >> 1;
- textColor.blue = textColor.blue + 65535 >> 1;
- }
-
- ::RGBForeColor(&textColor);
-
- UTextDrawing::DrawWithJustification((Ptr)&mText[1], mText[0], frame, just);
- }
-
-
- // the following functions are declared inline in the header file. The #pragma
- // mark let's them show up in the CW IDE's function popup for ease of navigation
- // and reference. :-)
-
- #pragma mark CVersCaption::GetVersion
- #pragma mark CVersCaption::SetVersion
- #pragma mark CVersCaption::GetUseShortString
- #pragma mark CVersCaption::SetUseShortString
- #pragma mark CVersCaption::GetUseCountryCode
- #pragma mark CVersCaption::SetUseCountryCode